package com.cherry.common.exception.enums;


import com.cherry.common.constant.CommonConstants;
import com.cherry.common.exception.IErrorCode;

import java.util.Arrays;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 通用系统异常编码（10000~20000）<p>
 * 通用业务异常编码（20000~30000）<p>
 * 框架组件异常编码（30000~40000）<p>
 * 业务异常编码（7位）：2位域编号 + 2位项目模块编号 + 3位状态编号<p>
 * 3位状态码：0~499为客户端错误，如：数据校验、权限校验、500~999为服务端错误，如：系统逻辑异常
 *
 * @author sinbad.cheng
 * @see IErrorCode
 */
public enum CommonErrorCode implements IErrorCode {

    /**
     * 失败：0
     */
    FAILURE(CommonConstants.FAILURE_CODE, CommonConstants.FAILURE_MSG),
    /**
     * 成功：1
     */
    SUCCESS(CommonConstants.SUCCESS_CODE, CommonConstants.SUCCESS_MSG),

    // ==========================  通用系统异常（10000~20000） ==========================
    // ==========================  请求异常（11000） ==========================
    /**
     * 参数错误：11000
     */
    PARAMS_ERROR(11000, "参数错误"),
    /**
     * 参数为空：11010
     */
    PARAMS_IS_NULL(11010, "参数为空"),
    /**
     * 参数格式错误：11020
     */
    PARAMS_FORMAT_ERROR(11020, "参数格式错误"),
    /**
     * 参数解析失败：11030
     */
    PARAMS_PARSING_FAILED(11030, "参数解析失败"),
    /**
     * 参数无效：11040
     */
    PARAMS_INVALID(11040, "参数无效"),
    /**
     * 参数包含非法字符：11050
     */
    PARAMS_CONTAIN_ILLEGAL_CHARACTERS(11050, "参数包含非法字符"),
    /**
     * 参数包含敏感词：11060
     */
    PARAMS_CONTAIN_SENSITIVE_WORDS(11060, "参数包含敏感词"),
    /**
     * 请求头错误：11200
     */
    REQUEST_HEADER_ERROR(11200, "请求头错误"),
    /**
     * 请求头缺失：11210
     */
    REQUEST_HEADER_IS_MISSING(11210, "请求头缺失"),
    /**
     * 请求正在处理中：11300
     */
    REQUEST_IS_BEING_PROCESSED(11300, "请求正在处理中"),
    /**
     * 未找到该请求：11410
     */
    REQUEST_NOT_FOUND(11410, "未找到该请求"),
    /**
     * 请求方式不支持：11420
     */
    REQUEST_METHOD_NOT_ALLOWED(11420, "请求方式不支持"),
    /**
     * 请求超时：11430
     */
    REQUEST_TIMEOUT(11430, "请求超时"),
    /**
     * 请求长度受限制：11440
     */
    REQUEST_LENGTH_REQUIRED(11440, "请求长度受限制"),
    /**
     * 不支持的媒体类型：11450
     */
    UNSUPPORTED_MEDIA_TYPE(11450, "不支持的媒体类型"),

    // ========================== 系统异常（12000） ==========================
    /**
     * 系统内部错误：12000
     */
    SERVER_ERROR(12000, "系统异常"),
    /**
     * 服务不可用：12100
     */
    SERVICE_UNAVAILABLE(12100, "服务不可用"),
    /**
     * 未知错误：12200
     */
    UNKNOWN_ERROR(12200, "未知错误"),

    // ========================== 限流降级（13000） ==========================
    /**
     * 系统繁忙，请稍后再试：13000
     */
    SYSTEM_BUSY(13000, "系统繁忙，请稍后再试"),
    /**
     * 重复请求，请稍后重试：13100
     */
    REPEATED_REQUEST(13100, "重复请求，请稍后重试"),
    /**
     * 请求次数超出限制：13200
     */
    REQUEST_EXCEEDS_LIMIT(13200, "请求次数超出限制"),
    /**
     * 请求并发数超出限制：13300
     */
    REQUEST_CONCURRENCY_EXCEEDS_LIMIT(13300, "请求并发数超出限制"),

    // ========================== 认证/授权（14000） ==========================
    /**
     * 没有访问权限：14000
     */
    FORBIDDEN(14000, "没有访问权限"),
    /**
     * 请求未授权：14100
     */
    UNAUTHORIZED(14100, "请求未授权"),
    /**
     * 认证失败：14200
     */
    AUTHENTICATION_FAILED(14200, "认证失败"),
    /**
     * 用户名或密码错误：14210
     */
    USER_NAME_OR_PASSWORD_ERROR(14210, "用户名或密码错误"),
    /**
     * 验证码错误：14220
     */
    VERIFICATION_CODE_ERROR(14220, "验证码错误"),
    /**
     * 时间戳校验失败：14230
     */
    TIMESTAMP_VERIFICATION_FAILED(14230, "时间戳校验失败"),
    /**
     * 签名校验失败：14240
     */
    SIGNATURE_VERIFICATION_FAILED(14240, "签名校验失败"),
    /**
     * token校验失败：14250
     */
    TOKEN_VERIFICATION_FAILED(14250, "token校验失败"),
    /**
     * 账号已禁用：14260
     */
    ACCOUNT_IS_DISABLED(14260, "账号已禁用"),
    /**
     * 该账号已在其它地方登录：14270
     */
    ACCOUNT_IS_ALREADY_LOGGED_IN_ELSEWHERE(14270, "该账号已在其它地方登录"),
    /**
     * 登录已失效，请重新登录：14280
     */
    LOGIN_EXPIRED(14280, "登录已失效，请重新登录"),
    /**
     * 接口已下线，请切换到新版本接口：14300
     */
    INTERFACE_IS_OFFLINE(14300, "接口已下线，请切换到新版本接口"),
    /**
     * 当前您的版本过低，无法使用最新功能，请更新应用：14310
     */
    APP_VERSION_IS_TOO_LOW(14310, "当前您的版本过低，无法使用最新功能，请更新应用"),

    // ========================== 通用数据异常（20000） ==========================
    /**
     * 查询失败：20010
     */
    QUERY_FAILED(20010, "查询失败"),
    /**
     * 保存失败：20020
     */
    SAVE_FAILED(20020, "保存失败"),
    /**
     * 更新失败：20030
     */
    UPDATE_FAILED(20030, "更新失败"),
    /**
     * 删除失败：20040
     */
    DELETE_FAILED(20040, "删除失败"),
    /**
     * 操作失败：20050
     */
    OPERATION_FAILED(20050, "操作失败"),
    /**
     * 数据不存在：20100
     */
    DATA_NOT_EXISTS(20100, "数据不存在"),
    /**
     * 数据已存在：20110
     */
    DATA_ALREADY_EXISTS(20110, "数据已存在"),
    /**
     * 数据已处理：20120
     */
    DATA_PROCESSED(20120, "数据已处理"),
    /**
     * 编号重复：20200
     */
    CODE_REPEATED(20200, "编号重复"),
    /**
     * 名称重复：20210
     */
    NAME_REPEATED(20210, "名称重复"),
    /**
     * 类型不支持：20300
     */
    TYPE_NOT_SUPPORTED(20300, "类型不支持"),
    /**
     * 类型不匹配：20310
     */
    TYPE_MISMATCH(20310, "类型不匹配"),
    /**
     * 状态异常：20320
     */
    STATUS_ABNORMAL(20320, "状态异常"),

    // ==========================  基础数据异常（21000） ==========================
    /**
     * 获取用户信息失败：21101
     */
    USER_GET_FAILED(21101, "获取用户信息失败"),
    /**
     * 用户不存在：21102
     */
    USER_NOT_EXISTS(21102, "用户不存在"),


    /**
     * 获取客户信息失败：21301
     */
    CUSTOMER_GET_FAILED(21301, "获取客户信息失败"),
    /**
     * 客户不存在：21302
     */
    CUSTOMER_NOT_EXISTS(21302, "客户不存在"),

    // ==========================  框架组件异常（30000~40000） ==========================
    // ==========================  任务异常（30100） ==========================
    /**
     * 未找到该任务：30101
     */
    TASK_NOT_FOUND(30101, "未找到该任务"),
    /**
     * 未找到任务处理器：30102
     */
    TASK_PROCESSOR_NOT_FOUND(30102, "未找到任务处理器"),
    /**
     * 任务拆分失败：30103
     */
    TASK_SPLIT_FAILED(30103, "任务拆分失败"),
    /**
     * 任务参数解析失败：30104
     */
    TASK_PARAMETER_PARSING_FAILED(30104, "任务参数解析失败"),
    /**
     * 任务执行中：30105
     */
    TASK_IN_PROGRESS(30105, "任务执行中"),
    /**
     * 任务已取消：30106
     */
    TASK_CANCELED(30106, "任务已取消"),
    /**
     * 任务已完成：30107
     */
    TASK_COMPLETED(30107, "任务已完成"),
    /**
     * 任务已休眠：30108
     */
    TASK_SLEEPING(30108, "任务已休眠"),
    /**
     * 任务参数格式错误：30109
     */
    TASK_PARAMETER_FORMAT_ERROR(30109, "任务参数格式错误"),

    // ==========================  导入导出异常（30200） ==========================
    /**
     * 导入失败：30201
     */
    IMPORT_FAILED(30201, "导入失败"),
    /**
     * 导入表头不匹配：30202
     */
    IMPORT_HEADER_MISMATCH(30202, "导入表头不匹配"),
    /**
     * 导入类型不匹配：30203
     */
    IMPORT_TYPE_MISMATCH(30203, "导入类型不匹配"),
    /**
     * 导入超出限制：30204
     */
    IMPORT_EXCEEDS_LIMIT(30204, "导入超出限制"),
    /**
     * 导出失败：30251
     */
    EXPORT_FAILED(30251, "导出失败"),
    /**
     * 导出类型不匹配：30252
     */
    EXPORT_TYPE_MISMATCH(30252, "导出类型不匹配"),
    /**
     * 导出超出限制：30253
     */
    EXPORT_EXCEEDS_LIMIT(30253, "导出超出限制"),

    // ==========================  文件异常（30300） ==========================
    /**
     * 文件不存在：30301
     */
    FILE_NOT_EXISTS(30301, "文件不存在"),
    /**
     * 文件已存在：30302
     */
    FILE_ALREADY_EXISTS(30302, "文件已存在"),
    /**
     * 文件上传失败：30303
     */
    FILE_UPLOAD_FAILED(30303, "文件上传失败"),
    /**
     * 文件下载失败：30304
     */
    FILE_DOWNLOAD_FAILED(30304, "文件下载失败"),
    /**
     * 文件格式不支持：30305
     */
    FILE_FORMAT_NOT_SUPPORTED(30305, "文件格式不支持"),
    /**
     * 文件校验失败：30306
     */
    FILE_VERIFICATION_FAILED(30306, "文件校验失败"),
    /**
     * 文件解析失败：30307
     */
    FILE_PARSING_FAILED(30307, "文件解析失败"),
    /**
     * 超出文件大小限制：30308
     */
    FILE_SIZE_EXCEEDS_LIMIT(30308, "超出文件大小限制"),
    ;

    /**
     * 状态码
     */
    final int code;

    /**
     * 消息
     */
    final String msg;

    /**
     * code -> CommonErrorCode 映射
     */
    private static final Map<Integer, CommonErrorCode> MAPPING = Arrays.stream(values())
            .collect(Collectors.toMap(CommonErrorCode::getCode, Function.identity()));

    /**
     * 获取通用异常枚举
     *
     * @param code 编号
     * @return CommonErrorCode 通用异常枚举
     */
    public static CommonErrorCode get(int code) {
        return MAPPING.get(code);
    }

    CommonErrorCode(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    @Override
    public int getCode() {
        return code;
    }

    @Override
    public String getMsg() {
        return msg;
    }

    @Override
    public String toString() {
        return "CommonErrorCode{" +
                "code=" + code +
                ", msg='" + msg + '\'' +
                '}';
    }

}